/*
 *
 * Copyright (c) 2020-2022, Java知识图谱 (http://www.altitude.xin).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package xin.altitude.cms.common.support;

/**
 * @author <a href="http://www.altitude.xin" target="_blank">Java知识图谱</a>
 * @author <a href="https://gitee.com/decsa/ucode-cms-vue" target="_blank">UCode CMS</a>
 * @author <a href="https://space.bilibili.com/1936685014" target="_blank">B站视频</a>
 **/

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public class FieldFilterSupport {
    // 想要保留的字段标识
    public static final String DYNC_INCLUDE = "DYNC_INCLUDE";
    // 想要过滤的字段标识
    public static final String DYNC_EXCLUDE = "DYNC_EXCLUDE";
    // jackson核心类 过滤属性全部由这个类完成
    private static final ObjectMapper INCLUDE_MAPPER = new ObjectMapper();
    private static final ObjectMapper EXCLUDE_MAPPER = new ObjectMapper();

    static {
        //解决jackson2无法反序列化LocalDateTime的问题
        //这里要注意时间属性上要加入 @JsonFormat 注解 否则无法正常解析
        INCLUDE_MAPPER.registerModule(new JavaTimeModule());
        EXCLUDE_MAPPER.registerModule(new JavaTimeModule());
    }

    /**
     * 过滤字段
     *
     * @param object  需要过滤的object
     * @param include 需要保留的字段
     * @param exclude 需要过滤的字段
     * @return
     */
    public static JSONObject filter(Object object, String include, String exclude) {
        if (include != null && include.length() > 0) {
            INCLUDE_MAPPER.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_INCLUDE, SimpleBeanPropertyFilter.filterOutAllExcept(include.split(","))));
            INCLUDE_MAPPER.addMixIn(object.getClass(), DynamicInclude.class);
            return doFilter(object, INCLUDE_MAPPER);
        } else if (exclude != null && exclude.length() > 0) {
            EXCLUDE_MAPPER.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_EXCLUDE, SimpleBeanPropertyFilter.serializeAllExcept(exclude.split(","))));
            EXCLUDE_MAPPER.addMixIn(object.getClass(), DynamicExclude.class);
            return doFilter(object, EXCLUDE_MAPPER);
        }
        return null;
    }

    /**
     * 返回过滤后的json格式的字符串
     *
     * @param object
     * @param mapper
     * @return
     */
    private static JSONObject doFilter(Object object, ObjectMapper mapper) {

        //将类转换成json字符串返回
        try {
            String valueAsString = mapper.writeValueAsString(object);
            return JSON.parseObject(valueAsString, JSONObject.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

}

